package com.item.read.ui;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.Messages;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBPanel;
import com.item.read.ContentAction;
import com.item.read.store.SettingConfig;
import com.item.read.store.SettingState;
import com.item.read.util.CacheUtils;
import com.item.read.util.JsoupHelp;
import com.item.read.vo.ContentVo;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class LeanENForm {
    JButton open= new JButton("open");
    public JPanel mainPanel = new JBPanel();
    private JTextField jTextField=new JTextField();
    private JBList jList = new JBList();
    private JComboBox<String> comboBox= new ComboBox<>( new String[]{"Top menu","Bottom left"});
    private int listIndex = -1;
    private int urlIndex = 0;
    private JTextField wordNumField = new JTextField();
    private JTextField findField = new JTextField();
    private Vector<String> vt = null;
    private List<String> directoryData = null;
    private List<String> urlDatas = null;
    private Vector<String> filterVt = null;
    private JTextField intervalField = new JTextField();
    private Map<Integer,Integer> differenceMap = new ConcurrentHashMap<>();
    private SettingConfig config = null;
    private int urlDepth = 0;
    private String path = "";
    public LeanENForm() {}
    public void createUI() {
        initUi();
        loadSysData();
        initMonitor();
    }

    private void initMonitor() {
        //文件选择
        open.addActionListener( e->{
            JFileChooser jfc=new JFileChooser();
            jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES );
            jfc.showDialog(new JLabel(), "select");
            File file=jfc.getSelectedFile();
            if(file.isFile()){
                jTextField.setText(file.getAbsolutePath());
                setData(file.getAbsolutePath());
            }
        });
        //列表点击事件
        jList.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                if(jList.getSelectedIndex() == -1) return;
                if(differenceMap != null && differenceMap.size() > 0){
                    listIndex = differenceMap.get(jList.getSelectedIndex());
                }else{
                    listIndex = jList.getSelectedIndex();
                }
                if(jTextField.getText().contains("http") && listIndex == 0 && urlDepth == 1){
                    vt = new Vector<>(directoryData);
                    urlDepth = 0;
                    dataProcessing(findField.getText());
                }else if(jTextField.getText().contains("http") && urlDepth == 0){
                    urlDepth = 1;
                    setData(jTextField.getText());
                }
            }
        });
        //路径输入框获取焦点事件
        jTextField.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
            }
            @Override
            public void focusLost(FocusEvent e) {
                if(jTextField.getText().contains("http") && !path.equals(jTextField.getText())){
                    // LeanENForm.this.onlineBookInitialization();
                    if(urlDatas!=null){
                        urlDatas.clear();
                    }
                    setData(jTextField.getText());
                    path = jTextField.getText();
                }
            }
        });
        //搜索框值改变事件
        findField.getDocument().addDocumentListener(new DocumentAdapter() {
            @Override
            protected void textChanged(@NotNull DocumentEvent e) {
                if(StringUtils.isNotEmpty(jTextField.getText())){
                    String text = findField.getText();
                    dataProcessing(text);
                }
            }
        });
        //字数输入框获取焦点事件
        wordNumField.addFocusListener(new FocusListener(){
            @Override
            public void focusGained(FocusEvent e) {
            }

            @Override
            public void focusLost(FocusEvent e) {
                if(!isNum(wordNumField.getText())){
                    Messages.showMessageDialog(
                            ProjectManager.getInstance().getDefaultProject(),
                            "Only integers can be filled in!",
                            "error",
                            Messages.getInformationIcon());
                    return;
                }
                String content = vt.stream().collect(Collectors.joining());
                vt = new Vector<>();
                extracted(content,
                        Integer.parseInt(wordNumField.getText()),
                        vt);
                dataProcessing(findField.getText());
            }
        });
    }
    //加载系统数据
    private void loadSysData() {
        config = SettingState.getInstance().getConfig();
        if (config != null) {
            path = config.getFilePath();
            this.jTextField.setText(config.getFilePath());
            this.comboBox.setSelectedIndex(config.getReadType());
            this.findField.setText(config.getFindText());
            if(config.getWordNum() > 0){
                this.wordNumField.setText(config.getWordNum()+"");
            }
            if(config.getInterval() > 0){
                this.intervalField.setText(config.getInterval()+"");
            }
            ContentVo contentVo = ContentAction.getContent();
            if(contentVo.getContent()!=null && contentVo.getContent().size() > 0){
                vt = new Vector(contentVo.getContent());
                if(config.getFilePath().contains("http")){
                    directoryData = contentVo.getDirectory();
                    urlDatas = contentVo.getUrls();
                    urlIndex = contentVo.getUrlIndex();
                    urlDepth = contentVo.getUrlDepth();
                    if(urlDepth == 1){
                        vt.set(0,"go back to the previous level!");
                    }
                }
                dataProcessing(config.getFindText());
            }else{
                urlDepth = config.getUrlDepth();
                urlIndex = config.getUrlIndex();
                setData(config.getFilePath());
            }
        }
    }

    /**
     * 初始化界面
     */
    private void initUi() {
        mainPanel.setLayout(new BorderLayout());
        JBPanel topPanel = new JBPanel<>(new GridLayout(3,0));

        JBPanel line1Panel = new JBPanel(new FlowLayout(0));
        line1Panel.add(new Label("Read Type:"));
        line1Panel.add(comboBox);

        line1Panel.add(new Label("Word Num:"));
        wordNumField.setText("20");
        line1Panel.add(wordNumField);

        line1Panel.add(new Label("Interval Seconds:"));
        intervalField.setText("8");
        line1Panel.add(intervalField);
        topPanel.add(line1Panel);

        JBPanel line2Panel = new JBPanel(new FlowLayout(0));
        line2Panel.add(new Label("Find Text:"));
        findField.setMinimumSize(new Dimension(300,30));
        findField.setPreferredSize(new Dimension(300, 30));
        line2Panel.add(findField);
        topPanel.add(line2Panel);

        JBPanel statusPane=new JBPanel(new FlowLayout(0));
        JLabel jLabel = new JLabel("File Path:");
        statusPane.add(jLabel);
        jTextField.setMinimumSize(new Dimension(300,30));
        jTextField.setPreferredSize(new Dimension(300, 30));
        statusPane.add(jTextField);
        statusPane.add(open);
        topPanel.add(statusPane);

        mainPanel.add(topPanel,BorderLayout.NORTH);
        mainPanel.add(jList,BorderLayout.CENTER);
    }

    /**
     * 初始化http请求数据
     */
    private void onlineBookInitialization() {
        try {
            Map<String,List<String>> titles = JsoupHelp.init(jTextField.getText());
            vt =  new Vector<>(titles.get("text"));
            directoryData = vt;
            urlDatas = new Vector<>(titles.get("url"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }


    /**
     * 过滤数据,最后为列表赋值
     * @param text
     */
    private void dataProcessing(String text) {
        differenceMap.clear();
        filterVt = new Vector();
        if(text == null || text.trim().isEmpty()){
            jList.setListData(vt);
        }else{
            for(int i = 0 ; i < vt.size();i++){
                if(StringUtils.contains(vt.get(i), text)){
                    differenceMap.put(filterVt.size(),i);
                    filterVt.add(vt.get(i));
                }
            }
            jList.setListData(filterVt);
        }
    }

    /**
     * 处理数据
     * @param filePath
     */
    private void setData(String filePath) {
        if(StringUtils.isEmpty(filePath)){
            return;
        }
        int word = 20;
        if(isNum(wordNumField.getText()) && Integer.parseInt(wordNumField.getText()) > 0){
            word = Integer.parseInt(wordNumField.getText());
        }
        if(filePath.contains("http")){
            if(urlDatas == null || urlDatas.size() == 0){
                onlineBookInitialization();
                urlIndex = 0;
                urlDepth = 0;
            }
            if(urlDepth > 0){
                String line = JsoupHelp.getText(urlDatas.get(listIndex),path);
                vt = new Vector<>();
                extracted(line,word,vt);
                vt.add(0,"go back to the previous level!");
                urlIndex = listIndex;
                urlDepth = 1;
            }
        }else{
            vt = readFile(filePath,word);
            urlIndex = 0;
            urlDepth = 0;
        }
        dataProcessing(this.findField.getText());
        listIndex = -1;
    }

    /**
     * 读取文件，按字数分割
     * @param filePath
     * @param word
     * @return
     */
    public static Vector readFile(String filePath,int word) {
        Vector<String> vt = new Vector<>();
        ApplicationManager.getApplication().runReadAction(new Runnable() {
            @Override
            public void run() {
                try {
                    if (StringUtils.isEmpty(filePath)) {
                        return;
                    }
                    FileInputStream fileInputStream = new FileInputStream(filePath);
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream,"UTF-8"));
                    String line = "";
                    while((line = bufferedReader.readLine())!=null){
                        extracted(line, word, vt);
                    }
                    bufferedReader.close();
                } catch (FileNotFoundException e2) {
                    e2.printStackTrace();
                } catch (IOException e3) {
                    e3.printStackTrace();
                }
            }
        });
        return vt;
    }

    /**
     * 按字数分割逻辑
     * @param line
     * @param word
     * @param vt
     */
    public static void extracted(String line, int word, Vector<String> vt) {
        if(StringUtils.isNotEmpty(line)) {
            if(line.length() > word){
                int point = line.length() / word;
                if(point%2!=0){
                    point++;
                }
                for(int i = 0 ; i <point;i++){
                    int left = i * word;
                    int right= (i+1) * word;
                    String temp = line.substring(left,right > line.length()? line.length():right);
                    if(StringUtils.isNotEmpty(temp.trim())){
                        vt.add(temp);
                    }
                }
            }else{
                if(StringUtils.isNotEmpty(line.trim())) {
                    vt.add(line);
                }
            }
        }
    }
    public JPanel getContentPane() {
        return mainPanel;
    }
    public boolean isNum(String str){
        try {
            Integer.parseInt(str);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    /**
     * 保存系统数据
     */
    public void apply() {
        if(!isNum(wordNumField.getText())){
            Messages.showMessageDialog(
                    ProjectManager.getInstance().getDefaultProject(),
                    "Only integers can be filled in!",
                    "error",
                    Messages.getInformationIcon());
            return;
        }
        if(!isNum(intervalField.getText())){
            Messages.showMessageDialog(
                    ProjectManager.getInstance().getDefaultProject(),
                    "Only integers can be filled in!",
                    "error",
                    Messages.getInformationIcon());
            return;
        }
        SettingConfig config=SettingState.getInstance().getConfig();
        String tempPath = config.getFilePath();
        config.setInterval(Integer.parseInt(this.intervalField.getText()));
        config.setFindText(this.findField.getText());
        config.setWordNum(Integer.parseInt(wordNumField.getText()));
        config.setReadType(comboBox.getSelectedIndex());
        config.setFilePath(this.jTextField.getText());
        config.setUrlIndex(urlIndex);
        config.setUrlDepth(urlDepth);
        if(listIndex!=-1){
            if(this.jTextField.getText().contains("http")){
                listIndex-=1;
            }
            config.setReadIndex(listIndex);
        }else{
            listIndex = config.getReadIndex();
        }
        SettingState.getInstance().setConfig(config);
        List vtCopy = new ArrayList(vt);
        if(urlDepth > 0){
            vtCopy.remove(0);
        }
        if(tempPath!=null && !tempPath.equals(this.jTextField.getText())){
            CacheUtils.flushCache();
        }
        ContentVo contentVo = new ContentVo(vtCopy,directoryData,urlDatas,listIndex,urlIndex,urlDepth,this.jTextField.getText());
        ContentAction.setContent(contentVo);
    }

    public boolean isModified() {
        return true;
    }
}
